// Fill out your copyright notice in the Description page of Project Settings.


#include "HotChunkFile.h"
#include "Json.h"
#include "App.h"
#include "Kismet/GameplayStatics.h"
#include "Math/UnitConversion.h"

TSharedPtr<FVersionWebInfo> UHotChunkFile::ConvertJsonToVersionVersionWebInfo(FString JsonContent)
{
	TSharedPtr<FVersionWebInfo> VersionWebInfo;

	TSharedPtr<FJsonObject> JsonParsed;
	TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonContent);
	if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
	{
		VersionWebInfo = MakeShareable(new FVersionWebInfo);

		TSharedPtr<FJsonObject> PlatformParsed = JsonParsed->GetObjectField(UGameplayStatics::GetPlatformName());

		const TArray<TSharedPtr<FJsonValue>> WebSites = PlatformParsed->GetArrayField("WebSites");
		for (int i = 0; i < WebSites.Num(); ++i)
		{
			VersionWebInfo->WebSites.Add(WebSites[i]->AsObject()->GetStringField(FString::FromInt(i)));
		}

		const TArray<TSharedPtr<FJsonValue>> ResSites = PlatformParsed->GetArrayField("ResSites");
		for (int i = 0; i < ResSites.Num(); ++i)
		{
			VersionWebInfo->ResSites.Add(ResSites[i]->AsObject()->GetStringField(FString::FromInt(i)));
		}

		VersionWebInfo->CloudDir = PlatformParsed->GetStringField("CloudDir");
		VersionWebInfo->ManifestDir = PlatformParsed->GetStringField("ManifestDir");
		VersionWebInfo->VersionFile = PlatformParsed->GetStringField("VersionFile");
	}

	return VersionWebInfo;
}

TSharedPtr<FVersionManifestInfo> UHotChunkFile::ConvertJsonToVersionManifestInfo(FString JsonContent)
{
	TSharedPtr<FVersionManifestInfo> VersionManifestInfo;

	TSharedPtr<FJsonObject> JsonParsed;
	TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonContent);

	if (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
	{
		VersionManifestInfo = MakeShareable(new FVersionManifestInfo(JsonParsed->GetStringField("ClientVersion"), JsonParsed->GetStringField("BuildUrl")));

		const TArray<TSharedPtr<FJsonValue>> Files = JsonParsed->GetArrayField("files");

		for (auto File : Files)
		{
			FString Filename = File->AsObject()->GetStringField("filename");
			// chenck the version and pak difference
			if (Filename.Contains(VersionManifestInfo->ClientVersion))
			{
				FString ChunkName = Filename;
				int32 StartIndex = FString(FApp::GetProjectName()).Len() + 1;
				int32 EndIndex = ChunkName.Find(VersionManifestInfo->ClientVersion);
				ChunkName.RemoveAt(EndIndex, ChunkName.Len() - EndIndex);
				ChunkName.RemoveAt(0, StartIndex);

				VersionManifestInfo->ChunkManifestInfos.Add(ChunkName, MakeShareable(new FChunkManifestInfo(
					Filename,
					File->AsObject()->GetStringField("uniqueFilename"),
					File->AsObject()->GetStringField("length"),
					File->AsObject()->GetStringField("URL"),
					File->AsObject()->GetStringField("hash"),
					File->AsObject()->GetStringField("hash256"),
					ChunkName
				)));
			}
		}
	}

	return VersionManifestInfo;
}

FString UHotChunkFile::ConvertVersionManifestInfoToJson(TSharedPtr<FVersionManifestInfo> VersionManifestInfo)
{
	TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);

	JsonObject->SetStringField("ClientVersion", VersionManifestInfo->ClientVersion);
	JsonObject->SetStringField("BuildUrl", VersionManifestInfo->BuildUrl);

	TArray<TSharedPtr<FJsonValue>> FilesArray;
	for (auto ChunkManifestInfo : VersionManifestInfo->ChunkManifestInfos)
	{
		TSharedPtr<FJsonObject> FileObject = MakeShareable(new FJsonObject);
		FileObject->SetStringField("filename", ChunkManifestInfo.Value->Filename);
		FileObject->SetStringField("uniqueFilename", ChunkManifestInfo.Value->UniqueFilename);
		FileObject->SetStringField("length", ChunkManifestInfo.Value->Length);
		FileObject->SetStringField("URL", ChunkManifestInfo.Value->URL);
		FileObject->SetStringField("hash", ChunkManifestInfo.Value->Hash);
		FileObject->SetStringField("hash256", ChunkManifestInfo.Value->Hash256);

		FilesArray.Add(MakeShareable(new FJsonValueObject(FileObject)));
	}

	JsonObject->SetArrayField("files", FilesArray);

	FString JsonContent;
	TSharedRef<TJsonWriter<TCHAR>> JsonWriter = TJsonWriterFactory<TCHAR>::Create(&JsonContent);
	FJsonSerializer::Serialize(JsonObject.ToSharedRef(), JsonWriter);

	return JsonContent;
}

float UHotChunkFile::GetDiskFreeSpace()
{
	uint64 TotalDiskSpace = 0;
	uint64 TotalDiskFreeSpace = 0;
	if (FPlatformMisc::GetDiskTotalAndFreeSpace(FPaths::ProjectDir(), TotalDiskSpace, TotalDiskFreeSpace))
	{
		double DiskFreeSpace = (double)TotalDiskFreeSpace;
		double DiskFreeSpaceMB = FUnitConversion::Convert(DiskFreeSpace, EUnit::Bytes, EUnit::Megabytes);
		return (float)DiskFreeSpaceMB;
	}
	return 0.0f;
}
